package org.kjtc.socket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class TcpServer {
	
	private int port = 8090;
	
	public void bind () {
        // 独立的NIO线程池，acceptor接收客户端TCP连接请求，将新创建的SocketChannel注册到I/O线程池
        // Acceptor线程池只用于客户端的登录、握手和安全认证，一旦链路建立成功，就将链路注册到后端I/O线程上
        EventLoopGroup acceptorGroup = new NioEventLoopGroup();
        // I/O线程池，负责SocketChannel的读写和编解码工作
        EventLoopGroup ioGroup = new NioEventLoopGroup();
        // 用于启动NIO服务端的辅助启动类，降低服务端的开发复杂度
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap.group(acceptorGroup, ioGroup)
                // 创建服务器端Channel
                .channel(NioServerSocketChannel.class)
                // 配置TCP参数，将它的backlog设置为1024
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 绑定处理I/O事件的处理类
                .childHandler(new ChildChannelHandler());
            // 绑定监听端口，同步阻塞方法sync等待绑定操作完成，ChannelFuture用于异步操作的通知回调
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            // 阻塞等待服务器端链路关闭后main函数退出
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 退出释放线程池资源
            acceptorGroup.shutdownGracefully();
            ioGroup.shutdownGracefully();
            System.out.println("服务器端链路关闭，资源释放");
        }

    }
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {

        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new TcpServerHandler());
        }
    }
}